from django.db import models
import json
from django.core.exceptions import ValidationError
from utils.models import CoreModel
from system.models import DictData, User
from utils.models import CommonStatus


class ProductStatus(models.TextChoices):
    ACTIVE = 'active', '激活'
    INACTIVE = 'inactive', '非激活'
    DISCONTINUED = 'discontinued', '已停产'
    
    @classmethod
    def get_choices_from_dict(cls):
        """从字典系统获取产品状态选项
        
        优先从系统字典中获取产品状态选项，如果字典中没有数据，则返回默认枚举值
        
        Returns:
            list: 状态选项列表，格式为[(value, label), ...]
        """
        # 使用lambda函数延迟查询执行，避免Django应用未初始化时的AppRegistryNotReady错误
        def get_choices():
            # 从字典系统获取产品状态选项
            status_dict_data = DictData.objects.filter(
                dict_type__value='product_status', 
                status=CommonStatus.ENABLED
            ).values_list('value', 'label')
            
            # 如果字典中没有数据，返回默认枚举值
            if not status_dict_data:
                return cls.choices
            
            return list(status_dict_data)
        
        return get_choices


class Product(CoreModel):
    """产品模型

    存储产品的基本信息，包括SKU、名称、描述、类别、计量单位等
    """
    product_id = models.AutoField(primary_key=True, verbose_name="产品ID", help_text="产品的唯一标识")
    product_type = models.CharField(max_length=64, blank=True, null=True, verbose_name="货品类型", help_text="货品类型")
    sku = models.CharField(max_length=50, verbose_name="SKU", unique=True, help_text="库存单元编码")
    name = models.CharField(max_length=255, verbose_name="货品名称", help_text="产品的全称")
    spc = models.CharField(max_length=255, blank=True, null=True, verbose_name="货品规格", help_text="产品的规格型号")
    description = models.TextField(blank=True, null=True, verbose_name="货品描述", help_text="产品的详细描述")
    category_id = models.IntegerField(blank=True, null=True, verbose_name="货品分类id", help_text="货品分类id")
    unit_pr = models.CharField(max_length=20, blank=True, null=True, verbose_name="采购计量单位", help_text="采购使用的计量单位")
    unit_wh = models.CharField(max_length=20, blank=True, null=True, verbose_name="库存计量单位", help_text="库存管理使用的计量单位")
    unit_use = models.CharField(max_length=20, blank=True, null=True, verbose_name="使用计量单位", help_text="生产使用的计量单位")
    unit_rate = models.JSONField(blank=True, null=True, verbose_name="计量单位转换率", help_text="不同计量单位之间的转换率")
    status = models.CharField(
        max_length=20,
        choices=ProductStatus.choices,  # 暂时使用默认枚举值，避免AppRegistryNotReady错误
        default=ProductStatus.ACTIVE,
        verbose_name="货品状态",
        help_text="产品的当前状态"
    )
    sku_supplier = models.CharField(max_length=64, blank=True, null=True, verbose_name="供应商SKU", help_text="供应商的库存单元编码")
    barcode = models.CharField(max_length=64, blank=True, null=True, verbose_name="条形码", help_text="产品的条形码")
    inventory_method = models.CharField(max_length=64, blank=True, null=True, verbose_name="库存方法", help_text="库存计价方法")
    costing_method = models.CharField(max_length=64, blank=True, null=True, verbose_name="成本计算方法", help_text="产品成本计算方法")
    is_batch_tracked = models.BooleanField(default=False, verbose_name="是否批次跟踪", help_text="是否需要批次跟踪")
    is_serial_tracked = models.BooleanField(default=False, verbose_name="是否序列号跟踪", help_text="是否需要序列号跟踪")
    shelf_life_days = models.IntegerField(blank=True, null=True, verbose_name="保质期天数", help_text="产品保质期天数")
    safety_stock = models.IntegerField(blank=True, null=True, verbose_name="安全库存", help_text="安全库存数量")
    reorder_point = models.IntegerField(blank=True, null=True, verbose_name="再订货点", help_text="再订货触发点数量")
    max_stock = models.IntegerField(blank=True, null=True, verbose_name="最大库存", help_text="最大库存数量")
    default_warehouse_id = models.IntegerField(blank=True, null=True, verbose_name="默认仓库ID", help_text="默认仓库的ID")
    default_location = models.CharField(max_length=64, blank=True, null=True, verbose_name="默认库位", help_text="默认库位")
    preferred_supplier_id = models.IntegerField(blank=True, null=True, verbose_name="首选供应商ID", help_text="首选供应商的ID")
    purchaser_id = models.IntegerField(blank=True, null=True, verbose_name="采购员ID", help_text="负责采购的人员ID")
    lead_time = models.IntegerField(blank=True, null=True, verbose_name="提前期", help_text="采购提前期(天)")
    moq = models.IntegerField(blank=True, null=True, verbose_name="最小起订量", help_text="最小起订数量")
    last_purchase_price = models.DecimalField(max_digits=14, decimal_places=4, blank=True, null=True, verbose_name="最近采购价", help_text="最近一次采购的价格")
    list_price = models.DecimalField(max_digits=14, decimal_places=4, blank=True, null=True, verbose_name="列表价", help_text="产品的标准销售价格")
    standard_cost = models.DecimalField(max_digits=14, decimal_places=4, blank=True, null=True, verbose_name="标准成本", help_text="产品的标准成本")
    current_cost = models.DecimalField(max_digits=14, decimal_places=4, blank=True, null=True, verbose_name="当前成本", help_text="产品的当前成本")
    income_account_id = models.IntegerField(blank=True, null=True, verbose_name="收入科目ID", help_text="收入会计科目的ID")
    cogs_account_id = models.IntegerField(blank=True, null=True, verbose_name="销售成本科目ID", help_text="销售成本会计科目的ID")
    asset_account_id = models.IntegerField(blank=True, null=True, verbose_name="资产科目ID", help_text="资产会计科目的ID")
    tax_code = models.CharField(max_length=64, blank=True, null=True, verbose_name="税码", help_text="产品的税率代码")
    version = models.CharField(max_length=64, blank=True, null=True, verbose_name="版本号", help_text="产品版本号")

    class Meta:
        verbose_name = "产品"
        verbose_name_plural = verbose_name
        ordering = ['sku']
        db_table = 'product'

    def __str__(self):
        return f"{self.name}({self.sku})"

    def clean(self):
        """
        验证unit_rate字段的格式是否正确
        期望格式: {"pr_wh": 1.0, "wh_use": 1.0, "pr_use": 1.0}
        """
        if self.unit_rate:
            try:
                # 确保unit_rate是有效的JSON格式
                if isinstance(self.unit_rate, str):
                    json.loads(self.unit_rate)
            except (json.JSONDecodeError, TypeError):
                raise ValidationError({
                    'unit_rate': '计量单位转换率必须是有效的JSON格式'
                })

    def save(self, *args, **kwargs):
        """保存前执行验证"""
        self.full_clean()
        super().save(*args, **kwargs)